package gui.houseeditor;

import gui.houseeditor.strategies.HouseDrawStrategy;
import gui.houseeditor.strategies.MinimalisticHouseDrawStrategy;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;

import javax.swing.JComponent;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class HouseEditorPane extends JComponent implements HouseDataListener {

	private class EditorListener extends MouseAdapter {

		@Override
		public void mouseDragged(MouseEvent e) {
			if (!isDrawable())
				return;
			if (new Rectangle(model.getWidth() * getCellSize(),
					model.getHeight() * getCellSize()).contains(e.getPoint()))
				if (SwingUtilities.isLeftMouseButton(e))
					model.setCell(paintingObject, e.getY() / getCellSize(),
							e.getX() / getCellSize());
		}

		@Override
		public void mouseClicked(MouseEvent e) {
			if (!isDrawable())
				return;
			if (new Rectangle(model.getWidth() * getCellSize(),
					model.getHeight() * getCellSize()).contains(e.getPoint()))
				if (SwingUtilities.isLeftMouseButton(e))
					model.setCell(paintingObject, e.getY() / getCellSize(),
							e.getX() / getCellSize());

		}

		@Override
		public void mouseWheelMoved(MouseWheelEvent e) {
			if (getCellSize() + e.getWheelRotation() > 0) {
				setCellSize(getCellSize() + e.getWheelRotation());
			}
		}

	}

	private HouseModel model;
	private int cellSize;
	private boolean drawable = true;
	private HouseModel.HouseObject paintingObject = HouseModel.HouseObject.BLANK;
	private HouseDrawStrategy strategy;

	public HouseEditorPane(int w, int h) {
		this(new DefaultHouseModel(w, h));
	}

	public HouseEditorPane(HouseModel m) {
		this(m, 5);
	}

	public HouseEditorPane(int w, int h, int cellSize) {
		this(new DefaultHouseModel(w, h), cellSize);
	}

	public HouseEditorPane(HouseModel m, int cellSize) {
		this(m, cellSize, new MinimalisticHouseDrawStrategy());
	}

	public HouseEditorPane(HouseModel m, int cellSize,
			HouseDrawStrategy strategy) {
		model = m;
		model.addWorldDataListener(this);
		EditorListener l = new EditorListener();
		this.addMouseMotionListener(l);
		this.addMouseListener(l);
		this.addMouseWheelListener(l);
		this.cellSize = cellSize;
		this.strategy = strategy;
		setSize(getPreferredSize());
	}

	@Override
	public Dimension getPreferredSize() {
		return new Dimension(model.getWidth() * getCellSize(),
				model.getHeight() * getCellSize());
	}

	public HouseModel getHouseModel() {
		return model;
	}

	public int getCellSize() {
		return cellSize;
	}

	public void setCellSize(int s) {
		if (s < 0)
			throw new IllegalArgumentException("Negative Cell Size: " + s);
		cellSize = s;
		setSize(getPreferredSize());
		repaint();
	}

	public void setDrawable(boolean drawable) {
		this.drawable = drawable;
	}

	public boolean isDrawable() {
		return drawable;
	}

	public void valueChanged(HouseDataEvent e) {
		repaint();
	}

	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.setColor(new Color(0, 0, 0));//colore di default nero
		for (int j = 0; j < model.getHeight(); j++)
			for (int i = 0; i < model.getWidth(); i++) {

				g.drawRect(i * getCellSize(), j * getCellSize(), getCellSize(),
						getCellSize());

				if (model.getCell(j, i) == HouseModel.HouseObject.WALL) {
					strategy.drawWall(g, i, j, cellSize);
				} else if (model.getCell(j, i) == HouseModel.HouseObject.LAMPADINA_ACCESA) {
					strategy.drawLampadinaAccesa(g, i, j, cellSize);
				} else if (model.getCell(j, i) == HouseModel.HouseObject.LAMPADINA_SPENTA) {
					strategy.drawLampadinaSpenta(g, i, j, cellSize);
				} else if (model.getCell(j, i) == HouseModel.HouseObject.PERSONA) {
					strategy.drawPersona(g, i, j, cellSize);
				} else if (model.getCell(j, i) == HouseModel.HouseObject.BLANK) {
					strategy.drawBlank(g, i, j, cellSize);
				} else if (model.getCell(j, i) == HouseModel.HouseObject.PORTA) {
					strategy.drawPorta(g, i, j, cellSize);
				}
			}

	}

	public void setPaintingObject(HouseModel.HouseObject o) {
		paintingObject = o;
	}
}
